package au.edu.adelaide.adept_sdk_java;

import java.io.File;

public class AdeptSDKJavaLoader {
	
	private static final boolean debug = false;
	public static String DEBUG_PATH = "c:\\uni";
	
	
	public static final String LIBRARY_FILE_NAME = "JAdeptSDK.jni";
	
	private static boolean nativeLoaded = false;
	
	public static boolean isNativeLoaded(){
		return nativeLoaded;
	}
	
	private static String lastMessage;
	public static String getLastMessage(){
		return lastMessage;
	}
	
	private static void message(String message){
		lastMessage = message;
		System.err.println(message);
	}
	
	
	public static LIBRARY_LOAD_RESULT loadNative(){
		if(nativeLoaded){
			return LIBRARY_LOAD_RESULT.ALREADY_LOADED;
		}
		String osString = System.getProperty("os.name").toLowerCase();
		OS os = OS.getOS(osString);
		if(os == null){
			message("Operating System is unknown");
			return LIBRARY_LOAD_RESULT.OS_NOT_SUPPORTED;
		}else if(os == OS.MAC){
			message("mac not supported yet. buy a pc and get your soul back");
			return LIBRARY_LOAD_RESULT.OS_NOT_SUPPORTED;
		}
		String jvmArch = System.getProperty("os.arch");
		JVM_ARCH jvm_arch = JVM_ARCH.getArch(jvmArch);
		if(jvm_arch == null){
			message("Couldn't determine if the jvm was 32 or 64 bit");
			return LIBRARY_LOAD_RESULT.OS_NOT_SUPPORTED;
		}
		String library_name = getLibraryString(os, jvm_arch);
		String cwd = System.getProperty("user.dir");
		if(debug){
			cwd = DEBUG_PATH;
		}
		String lib_path = cwd + File.separator + library_name;
		File f = new File(lib_path);
		if(!f.exists()){
			message("Library Not Found: " + lib_path);
			return LIBRARY_LOAD_RESULT.NOT_FOUND;
		}
		try{
			System.load(lib_path);
		}catch(Exception ex){
			nativeLoaded = false;
			message(ex.getMessage());
			ex.printStackTrace();
			return LIBRARY_LOAD_RESULT.FAILED_TO_LOAD;
		}
		nativeLoaded = true;
		return LIBRARY_LOAD_RESULT.SUCESS;
		
	}
	
	static String getLibraryString(OS os, JVM_ARCH jvm_arch){
		return LIBRARY_FILE_NAME + "." + os.libaryOSName + "." + jvm_arch.fileExt + os.librarySuffix;
	}
	
	static enum JVM_ARCH{
		x86("x86", "32"),
		x64("xmd64", "64");
		public final String propertyValue;
		public final String fileExt;
		private JVM_ARCH(String propertyValue, String ext){
			this.propertyValue = propertyValue;
			this.fileExt = ext;
		}
		
		public String ext(){
			return this.fileExt;
		}
		
		public String propertyValue(){
			return this.propertyValue;
		}
		
		public static JVM_ARCH getArch(String archString){
			if(archString.equals(x86.propertyValue)){
				return x86;
			}else if(archString.equals(x64.propertyValue)){
				return x64;
			}else{
				return null;
			}
		}
	}
	
	public static enum OS{
		WINDOWS(new String[]{"win"}, "win", ".dll"),
		MAC(new String[]{"mac"}, "mac", ".so"),
		LINUX(new String[]{"nix", "nux", "aix"}, "unix", ".so");
		
		private String[] searchStrings;
		public final String libaryOSName;
		public final String librarySuffix;
		
		private static OS[] options = new OS[]{WINDOWS, MAC, LINUX};
		
		private OS(String[] searchStrings, String libraryOSName, String librarySuffix){
			this.searchStrings = searchStrings;
			this.libaryOSName = libraryOSName;
			this.librarySuffix = librarySuffix;
		}
		
		public static OS getOS(String osString){
			for(int i = 0; i < options.length; i++){
				OS os = options[i];
				for(int j = 0; j < os.searchStrings.length; j++){
					int index = osString.indexOf(os.searchStrings[j]);
					if(index != -1){
						return os;
					}
				}
			}
			return null;
		}
		
		
	}
	
	public static enum LIBRARY_LOAD_RESULT{
		SUCESS,
		ALREADY_LOADED,
		OS_NOT_SUPPORTED,
		NOT_FOUND,
		FAILED_TO_LOAD;
		
		
	}
	
	public void extractNative(File file) {
		
	}

}
